home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / demos / gears.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-12-15  |  7.9 KB  |  336 lines

  1. /* $Id: gears.c,v 3.0 1998/02/14 18:42:29 brianp Exp $ */
  2.  
  3. /*
  4.  * 3-D gear wheels.  This program is in the public domain.
  5.  *
  6.  * Brian Paul
  7.  */
  8.  
  9. /* Conversion to GLUT by Mark J. Kilgard */
  10.  
  11. /*
  12.  * $Log: gears.c,v $
  13.  * Revision 3.0  1998/02/14 18:42:29  brianp
  14.  * initial rev
  15.  *
  16.  */
  17.  
  18.  
  19. #include <math.h>
  20. #include <stdlib.h>
  21. #include <GL/glut.h>
  22.  
  23. #ifndef M_PI
  24. #define M_PI 3.14159265
  25. #endif
  26.  
  27. /**
  28.  
  29.   Draw a gear wheel.  You'll probably want to call this function when
  30.   building a display list since we do a lot of trig here.
  31.  
  32.   Input:  inner_radius - radius of hole at center
  33.       outer_radius - radius at center of teeth
  34.       width - width of gear
  35.       teeth - number of teeth
  36.       tooth_depth - depth of tooth
  37.  
  38.  **/
  39.  
  40. static void
  41. gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
  42.   GLint teeth, GLfloat tooth_depth)
  43. {
  44.   GLint i;
  45.   GLfloat r0, r1, r2;
  46.   GLfloat angle, da;
  47.   GLfloat u, v, len;
  48.  
  49.   r0 = inner_radius;
  50.   r1 = outer_radius - tooth_depth / 2.0;
  51.   r2 = outer_radius + tooth_depth / 2.0;
  52.  
  53.   da = 2.0 * M_PI / teeth / 4.0;
  54.  
  55.   glShadeModel(GL_FLAT);
  56.  
  57.   glNormal3f(0.0, 0.0, 1.0);
  58.  
  59.   /* draw front face */
  60.   glBegin(GL_QUAD_STRIP);
  61.   for (i = 0; i <= teeth; i++) {
  62.     angle = i * 2.0 * M_PI / teeth;
  63.     glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
  64.     glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
  65.     glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
  66.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
  67.   }
  68.   glEnd();
  69.   /* draw front sides of teeth */
  70.   glBegin(GL_QUADS);
  71.   da = 2.0 * M_PI / teeth / 4.0;
  72.   for (i = 0; i < teeth; i++) {
  73.     angle = i * 2.0 * M_PI / teeth;
  74.  
  75.     glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
  76.     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
  77.     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
  78.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
  79.   }
  80.   glEnd();
  81.   glNormal3f(0.0, 0.0, -1.0);
  82.  
  83.   /* draw back face */
  84.   glBegin(GL_QUAD_STRIP);
  85.   for (i = 0; i <= teeth; i++) {
  86.     angle = i * 2.0 * M_PI / teeth;
  87.     glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
  88.     glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
  89.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
  90.     glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
  91.   }
  92.   glEnd();
  93.  
  94.   /* draw back sides of teeth */
  95.   glBegin(GL_QUADS);
  96.   da = 2.0 * M_PI / teeth / 4.0;
  97.   for (i = 0; i < teeth; i++) {
  98.     angle = i * 2.0 * M_PI / teeth;
  99.  
  100.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
  101.     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
  102.     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
  103.     glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
  104.   }
  105.   glEnd();
  106.   /* draw outward faces of teeth */
  107.   glBegin(GL_QUAD_STRIP);
  108.   for (i = 0; i < teeth; i++) {
  109.     angle = i * 2.0 * M_PI / teeth;
  110.  
  111.     glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
  112.     glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
  113.     u = r2 * cos(angle + da) - r1 * cos(angle);
  114.     v = r2 * sin(angle + da) - r1 * sin(angle);
  115.     len = sqrt(u * u + v * v);
  116.     u /= len;
  117.     v /= len;
  118.     glNormal3f(v, -u, 0.0);
  119.     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
  120.     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
  121.     glNormal3f(cos(angle), sin(angle), 0.0);
  122.     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
  123.     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
  124.     u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
  125.     v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
  126.     glNormal3f(v, -u, 0.0);
  127.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
  128.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
  129.     glNormal3f(cos(angle), sin(angle), 0.0);
  130.   }
  131.   glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
  132.   glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
  133.  
  134.   glEnd();
  135.  
  136.   glShadeModel(GL_SMOOTH);
  137.  
  138.   /* draw inside radius cylinder */
  139.   glBegin(GL_QUAD_STRIP);
  140.   for (i = 0; i <= teeth; i++) {
  141.     angle = i * 2.0 * M_PI / teeth;
  142.     glNormal3f(-cos(angle), -sin(angle), 0.0);
  143.     glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
  144.     glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
  145.   }
  146.   glEnd();
  147.  
  148. }
  149.  
  150. static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
  151. static GLint gear1, gear2, gear3;
  152. static GLfloat angle = 0.0;
  153.  
  154. static GLuint limit;
  155. static GLuint count = 1;
  156.  
  157. static void
  158. draw(void)
  159. {
  160.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  161.  
  162.   glPushMatrix();
  163.   glRotatef(view_rotx, 1.0, 0.0, 0.0);
  164.   glRotatef(view_roty, 0.0, 1.0, 0.0);
  165.   glRotatef(view_rotz, 0.0, 0.0, 1.0);
  166.  
  167.   glPushMatrix();
  168.   glTranslatef(-3.0, -2.0, 0.0);
  169.   glRotatef(angle, 0.0, 0.0, 1.0);
  170.   glCallList(gear1);
  171.   glPopMatrix();
  172.  
  173.   glPushMatrix();
  174.   glTranslatef(3.1, -2.0, 0.0);
  175.   glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
  176.   glCallList(gear2);
  177.   glPopMatrix();
  178.  
  179.   glPushMatrix();
  180.   glTranslatef(-3.1, 4.2, 0.0);
  181.   glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
  182.   glCallList(gear3);
  183.   glPopMatrix();
  184.  
  185.   glPopMatrix();
  186.  
  187.   glutSwapBuffers();
  188.  
  189.   count++;
  190.   if (count == limit) {
  191.     exit(0);
  192.   }
  193. }
  194.  
  195. static void
  196. idle(void)
  197. {
  198.   angle += 2.0;
  199.   glutPostRedisplay();
  200. }
  201.  
  202. /* change view angle, exit upon ESC */
  203. /* ARGSUSED1 */
  204. static void
  205. key(unsigned char k, int x, int y)
  206. {
  207.   switch (k) {
  208.   case 'z':
  209.     view_rotz += 5.0;
  210.     break;
  211.   case 'Z':
  212.     view_rotz -= 5.0;
  213.     break;
  214.   case 27:  /* Escape */
  215.     exit(0);
  216.     break;
  217.   default:
  218.     return;
  219.   }
  220.   glutPostRedisplay();
  221. }
  222.  
  223. /* change view angle */
  224. /* ARGSUSED1 */
  225. static void
  226. special(int k, int x, int y)
  227. {
  228.   switch (k) {
  229.   case GLUT_KEY_UP:
  230.     view_rotx += 5.0;
  231.     break;
  232.   case GLUT_KEY_DOWN:
  233.     view_rotx -= 5.0;
  234.     break;
  235.   case GLUT_KEY_LEFT:
  236.     view_roty += 5.0;
  237.     break;
  238.   case GLUT_KEY_RIGHT:
  239.     view_roty -= 5.0;
  240.     break;
  241.   default:
  242.     return;
  243.   }
  244.   glutPostRedisplay();
  245. }
  246.  
  247. /* new window size or exposure */
  248. static void
  249. reshape(int width, int height)
  250. {
  251.   GLfloat h = (GLfloat) height / (GLfloat) width;
  252.  
  253.   glViewport(0, 0, (GLint) width, (GLint) height);
  254.   glMatrixMode(GL_PROJECTION);
  255.   glLoadIdentity();
  256.   glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
  257.   glMatrixMode(GL_MODELVIEW);
  258.   glLoadIdentity();
  259.   glTranslatef(0.0, 0.0, -40.0);
  260. }
  261.  
  262. static void
  263. init(void)
  264. {
  265.   static GLfloat pos[4] =
  266.   {5.0, 5.0, 10.0, 0.0};
  267.   static GLfloat red[4] =
  268.   {0.8, 0.1, 0.0, 1.0};
  269.   static GLfloat green[4] =
  270.   {0.0, 0.8, 0.2, 1.0};
  271.   static GLfloat blue[4] =
  272.   {0.2, 0.2, 1.0, 1.0};
  273.  
  274.   glLightfv(GL_LIGHT0, GL_POSITION, pos);
  275.   glEnable(GL_CULL_FACE);
  276.   glEnable(GL_LIGHTING);
  277.   glEnable(GL_LIGHT0);
  278.   glEnable(GL_DEPTH_TEST);
  279.  
  280.   /* make the gears */
  281.   gear1 = glGenLists(1);
  282.   glNewList(gear1, GL_COMPILE);
  283.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
  284.   gear(1.0, 4.0, 1.0, 20, 0.7);
  285.   glEndList();
  286.  
  287.   gear2 = glGenLists(1);
  288.   glNewList(gear2, GL_COMPILE);
  289.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
  290.   gear(0.5, 2.0, 2.0, 10, 0.7);
  291.   glEndList();
  292.  
  293.   gear3 = glGenLists(1);
  294.   glNewList(gear3, GL_COMPILE);
  295.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
  296.   gear(1.3, 2.0, 0.5, 10, 0.7);
  297.   glEndList();
  298.  
  299.   glEnable(GL_NORMALIZE);
  300. }
  301.  
  302. void 
  303. visible(int vis)
  304. {
  305.   if (vis == GLUT_VISIBLE)
  306.     glutIdleFunc(idle);
  307.   else
  308.     glutIdleFunc(NULL);
  309. }
  310.  
  311. int main(int argc, char *argv[])
  312. {
  313.   glutInit(&argc, argv);
  314.   if (argc > 1) {
  315.     /* do 'n' frames then exit */
  316.     limit = atoi(argv[1]) + 1;
  317.   } else {
  318.     limit = 0;
  319.   }
  320.   glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
  321.  
  322.   glutInitWindowPosition(0, 0);
  323.   glutInitWindowSize(300, 300);
  324.   glutCreateWindow("Gears");
  325.   init();
  326.  
  327.   glutDisplayFunc(draw);
  328.   glutReshapeFunc(reshape);
  329.   glutKeyboardFunc(key);
  330.   glutSpecialFunc(special);
  331.   glutVisibilityFunc(visible);
  332.  
  333.   glutMainLoop();
  334.   return 0;             /* ANSI C requires main to return int. */
  335. }
  336.